package gov.kqqzyyy.monkey.orderpad.service;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.CountDownTimer;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.SystemClock;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.core.content.FileProvider;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.socks.library.KLog;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.util.Date;
import java.util.Objects;

import gov.kqqzyyy.monkey.orderpad.R;
import gov.kqqzyyy.monkey.orderpad.mytools.CurrentVersion;
import gov.kqqzyyy.monkey.orderpad.mytools.DateTimeUtil;
import gov.kqqzyyy.monkey.orderpad.mytools.MyApplication;
import gov.kqqzyyy.monkey.orderpad.mytools.MyServiceUtil;
import gov.kqqzyyy.monkey.orderpad.mytools.UpdateInfo;
import gov.kqqzyyy.monkey.orderpad.network.bean.BaseResponse;
import retrofit2.Call;
import retrofit2.Callback;

@SuppressWarnings("NullableProblems")
public class UpdateService extends Service {

    private boolean isThreadRunning = false;
    private boolean isCheckingUpdate = true;

    private int newVerCode;
    private String newVerName;
    private String updateInfo;
    private ToServiceReceiver toServiceReceiver = null;

    private String downLoadUri = null;
    private String downLoadPath = null;

    private UpdateThread updateThread;

    private MyApplication myApplication;

    private Call<String> systemTimeCall;

    private Thread downloadThread;
    private CountDownTimer timer;
    private MyHandler handler = null;

    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    @Override
    public void onCreate() {
        super.onCreate();
//        downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
        downLoadPath = Objects.requireNonNull(getApplicationContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)).getAbsolutePath();
        myApplication = (MyApplication) getApplication();
        downLoadUri = getResources().getString(R.string.update_url);//服务器地址
        toServiceReceiver = new ToServiceReceiver();
        IntentFilter intentFilter = new IntentFilter("toUpdateService");
        registerReceiver(toServiceReceiver, intentFilter);

        handler = new MyHandler(UpdateService.this);
    }

    private static class MyHandler extends Handler {
        WeakReference<UpdateService> mService;

        MyHandler(UpdateService service) {
            mService = new WeakReference<>(service);
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            super.handleMessage(msg);
            UpdateService service = mService.get();
            //下载文件超时
            if (msg.what == 0x10) {
                service.downloadThread.interrupt();
                if (service.timer != null) {
                    service.timer.cancel();
                    service.timer = null;
                }
                Intent intent = new Intent("updatebroadcast");
                intent.putExtra("updatecode", 0x15);
                service.sendBroadcast(intent);
            }
        }
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (updateThread == null) {
            updateThread = new UpdateThread();
        }
        if (!updateThread.isAlive()) {
            isThreadRunning = true;
            isCheckingUpdate = true;
            updateThread.start();
        }
        doGetServerTime();
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        stopUpdateThread();
        unregisterReceiver(toServiceReceiver);
        if (systemTimeCall != null && systemTimeCall.isExecuted()) {
            systemTimeCall.cancel();
        }
    }

    private void stopUpdateThread() {
        if (updateThread != null && updateThread.isAlive()) {
            isThreadRunning = false;
            isCheckingUpdate = false;
            updateThread.interrupt();
            updateThread = null;
        }
    }

    //更新线程
    private class UpdateThread extends Thread {
        @Override
        public void run() {
            super.run();
            int result;
            while (isThreadRunning) {
                if (isCheckingUpdate) {//检查更新
                    isCheckingUpdate = false;
                    Intent intent = new Intent("updatebroadcast");
                    if (isNetWorkAvailable()) {//网络连接是否可用
                        if (getServerVersionCode()) {//获取服务器版本
                            int currentCode = CurrentVersion.getVerCode(UpdateService.this);//本地应用版本
                            if (newVerCode > currentCode) {
                                intent.putExtra("newVerCode", newVerCode);
                                intent.putExtra("newVerName", newVerName);
                                intent.putExtra("updateInfo", updateInfo);
                                result = 0x12;
                            } else {
                                result = 0x11;
                            }
                            intent.putExtra("updatecode", result);//更新代码,0x11：无更新，0x12：有更新
                        } else {
                            intent.putExtra("updatecode", 0x18);//0x18无法连接到服务器
                        }
                    } else {
                        intent.putExtra("updatecode", 0x17);//0x17网络无连接
                    }
                    isThreadRunning = false;
                    sendBroadcast(intent);
                    stopUpdateThread();
                }
                SystemClock.sleep(5000);
            }
        }
    }

    //判断网络是否可用
    private boolean isNetWorkAvailable() {
        ConnectivityManager conn = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = conn != null ? conn.getActiveNetworkInfo() : null;
        return networkInfo != null && networkInfo.isAvailable();
    }

    //获取服务器版本号
    private boolean getServerVersionCode() {
        try {
            String newVerJSON = UpdateInfo.getUpdateVerJSON(UpdateService.this);
            if (newVerJSON == null || newVerJSON.equals("") || newVerJSON.startsWith("<!DOCTYPE html>")) {
                return false;
            } else {
                JSONArray jsonArray = new JSONArray(newVerJSON);
                if (jsonArray.length() > 0) {
                    for (int i = 0; i < jsonArray.length(); i++) {
                        JSONObject object = jsonArray.getJSONObject(i);
                        if (object.getString("apkname").equals(getResources().getString(R.string.apk_name))) {
                            newVerCode = Integer.parseInt(object.getString("vercode"));
                            newVerName = object.getString("vername");
                            updateInfo = object.getString("updateInfo");
                            String qssj = object.getString("qssj");
                            String jssj = object.getString("jssj");
                            myApplication.setQssj(qssj);
                            myApplication.setJssj(jssj);
                            return true;
                        }
                    }
                }
            }
        } catch (Exception e) {
            KLog.d("APE", e.getMessage());
            e.printStackTrace();
            return false;
        }
        return false;
    }

//    private void doDownLoadFile() {
//        String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();
//        String apkName = getResources().getString(R.string.apk_name);
////        String path = Objects.requireNonNull(getApplicationContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)).getAbsolutePath();
//        if (!FileUtil.deleteDirWihtFile(new File(path))) {
//            KLog.d("删除旧文件失败！");
//        }
//        String apkUrl = "http://" + downLoadPath + File.separator + getResources().getString(R.string.apk_name);
//        Uri uri = Uri.parse(apkUrl);
//        DownloadManager.Request request = new DownloadManager.Request(uri);
//        request.setDestinationInExternalFilesDir(getApplicationContext(), path, getResources().getString(R.string.apk_name));
//        request.setMimeType("application/vnd.android.package-archive");
//        downLoadApkID = downloadManager.enqueue(request);
//    }

    //下载应用apk文件()
    private void downloadApkFile() {
        final String url = "http://" + downLoadUri + "/" + getResources().getString(R.string.apk_name);
        downloadThread = new Thread(() -> {
            HttpClient client = new DefaultHttpClient();
            HttpGet get = new HttpGet(url);
            Intent intent = new Intent("updatebroadcast");
            try {
                HttpResponse response = client.execute(get);
                String responseResult = response.getStatusLine().toString();
                if (responseResult.equals("HTTP/1.1 404 Not Found")) {
                    intent.putExtra("updatecode", 0x14);//0x14文件下载不存在
                    sendBroadcast(intent);
                    return;
                }
                HttpEntity entity = response.getEntity();
                InputStream inputStream = entity.getContent();

                File file = new File(downLoadPath, getResources()
                        .getString(R.string.apk_name));
                if (file.exists()) {
                    if (!file.delete()) {
                        KLog.d("delete apk failed");
                    }
                }
                if (!file.createNewFile()) {
                    KLog.d("create apk failed");
                }
                FileOutputStream fileOutputStream = new FileOutputStream(file);
                byte[] bytes = new byte[1024];
                int ch;
                while ((ch = inputStream.read(bytes)) != -1) {
                    fileOutputStream.write(bytes, 0, ch);
                }
                fileOutputStream.flush();
                inputStream.close();
                fileOutputStream.close();
                if (timer != null) {
                    timer.cancel();
                    timer = null;
                }
                intent.putExtra("updatecode", 0x13);//0x13文件下载完成
                sendBroadcast(intent);
                downloadThread.interrupt();
            } catch (Exception e) {
                KLog.d(e.getMessage());
                e.printStackTrace();
            }
        });
        downloadThread.start();
        timer = new CountDownTimer(20000, 10000) {

            @Override
            public void onTick(long millisUntilFinished) {

            }

            @Override
            public void onFinish() {
                Message msg = new Message();
                msg.what = 0x10;
                handler.sendMessage(msg);
            }
        };
        timer.start();
    }

    private void installNewApk() {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        Uri fileUri = null;
        File apkFile = new File(downLoadPath, getResources().getString(R.string.apk_name));
        if (apkFile.exists()) {
            fileUri = FileProvider.getUriForFile(getApplicationContext(), "com.monkey.orderfileprovider", apkFile);
        }
        if (fileUri != null) {
            intent.setDataAndType(fileUri, "application/vnd.android.package-archive");
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);
        }
    }


//    private void installByID() {
//
//        Intent intent = new Intent(Intent.ACTION_VIEW);
//        intent.addCategory(Intent.CATEGORY_DEFAULT);
//        Uri fileUri = null;
////        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
////            fileUri = downloadManager.getUriForDownloadedFile(downLoadApkID);
////        } else {
//        File apkFile = queryDownloadedApk();
//        if (apkFile.exists()) {
////                fileUri = Uri.fromFile(apkFile); //模拟器安装
//            fileUri = FileProvider.getUriForFile(getApplicationContext(), "com.monkey.orderfileprovider", apkFile);//平板更新
//        }
////        }
//        if (fileUri != null) {
//            intent.setDataAndType(fileUri, "application/vnd.android.package-archive");
//            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
//            startActivity(intent);
//        }
//    }

//    private File queryDownloadedApk() {
//        File targetApkFile = null;
//        if (downLoadApkID != -1) {
//            DownloadManager.Query query = new DownloadManager.Query();
//            query.setFilterById(downLoadApkID);
//            query.setFilterByStatus(DownloadManager.STATUS_SUCCESSFUL);
//            Cursor cur = downloadManager.query(query);
//            if (cur != null) {
//                if (cur.moveToFirst()) {
//                    String uriString = cur.getString(cur.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
//                    targetApkFile = new File(Objects.requireNonNull(Uri.parse(uriString).getPath()));
//                }
//                cur.close();
//            }
//        }
//        return targetApkFile;
//    }

    private class ToServiceReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            int code = intent.getIntExtra("toservice", -1);
            switch (code) {
                case -1:
                    break;
                case 0x11://确认更新
//                    doDownLoadFile();
                    downloadApkFile();
                    break;
                case 0x12://更新检查
                    isCheckingUpdate = true;
                    break;
                case 0x13:
//                    installByID();
                    installNewApk();
                    break;

            }
        }
    }

    //获取服务器时间
    private void doGetServerTime() {
        systemTimeCall = MyServiceUtil.getSystemTimeCall();
        Callback<String> callback = new Callback<String>() {
            @Override
            public void onResponse(Call<String> call, retrofit2.Response<String> response) {
                String result = response.body();
                if (result != null) {
                    Gson gson = new Gson();
                    BaseResponse<String> resObj = gson.fromJson(result, new TypeToken<BaseResponse<String>>() {
                    }.getType());
                    String timeStr = resObj.getData();
                    Date serverDate = DateTimeUtil.getDTFormatDateTime(timeStr);
                    if (serverDate != null) {
                        long delta = serverDate.getTime() - new Date(System.currentTimeMillis()).getTime();
                        myApplication.setDeltaTime(delta);
                        Toast.makeText(getApplicationContext(), "获取服务器时间成功！", Toast.LENGTH_SHORT).show();
                    }
                }
            }

            @Override
            public void onFailure(Call<String> call, Throwable t) {
                Toast.makeText(getApplicationContext(), "获取服务器时间出错:" + t.toString(), Toast.LENGTH_SHORT).show();
            }
        };
        systemTimeCall.enqueue(callback);
    }

}
